<template>
  <div class="file-upload-container">
    <el-upload
      :action="action"
      :auto-upload="false"
      :on-change="handleChange"
      :on-remove="handleRemove"
      :before-upload="beforeUpload"
      :file-list="fileList"
      :limit="limit"
      :multiple="multiple"
      :accept="accept"
      :disabled="disabled || loading"
      :drag="drag"
    >
      <template #trigger>
        <el-button :type="buttonType" :icon="buttonIcon" :disabled="disabled || loading">{{ buttonText }}</el-button>
      </template>
      
      <template #tip v-if="tip">
        <div class="el-upload__tip">{{ tip }}</div>
      </template>
      
      <template #default v-if="drag">
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">
          将文件拖到此处，或<em>点击上传</em>
        </div>
        <div class="el-upload__tip" v-if="tip">{{ tip }}</div>
      </template>
    </el-upload>
    
    <div class="upload-actions" v-if="fileList.length > 0 && !autoUpload">
      <el-button type="primary" @click="submitUpload" :loading="loading" :disabled="disabled">
        {{ uploadButtonText }}
      </el-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, defineProps, defineEmits } from 'vue';
import { ElMessage } from 'element-plus';
import { UploadFilled } from '@element-plus/icons-vue';
import { uploadFile, uploadImage } from '../../services/upload';

const props = defineProps({
  // 上传类型：file-文件上传，image-图片上传
  uploadType: {
    type: String,
    default: 'file'
  },
  // 文件类型
  fileType: {
    type: String,
    default: 'document'
  },
  // 是否自动上传
  autoUpload: {
    type: Boolean,
    default: false
  },
  // 上传按钮文本
  buttonText: {
    type: String,
    default: '选择文件'
  },
  // 上传按钮类型
  buttonType: {
    type: String,
    default: 'primary'
  },
  // 上传按钮图标
  buttonIcon: {
    type: String,
    default: 'el-icon-upload'
  },
  // 上传按钮文本
  uploadButtonText: {
    type: String,
    default: '上传文件'
  },
  // 提示文本
  tip: {
    type: String,
    default: ''
  },
  // 最大上传数量
  limit: {
    type: Number,
    default: 1
  },
  // 是否支持多选
  multiple: {
    type: Boolean,
    default: false
  },
  // 接受的文件类型
  accept: {
    type: String,
    default: ''
  },
  // 是否禁用
  disabled: {
    type: Boolean,
    default: false
  },
  // 是否使用拖拽上传
  drag: {
    type: Boolean,
    default: false
  },
  // 最大文件大小（MB）
  maxSize: {
    type: Number,
    default: 10
  }
});

const emit = defineEmits(['success', 'error', 'change', 'remove']);

const fileList = ref<any[]>([]);
const loading = ref(false);

// 计算上传地址（实际上传不会使用这个地址，这里只是为了满足el-upload的要求）
const action = computed(() => {
  return props.uploadType === 'file' ? '/upload/file' : '/upload/image';
});

// 文件上传前的验证
const beforeUpload = (file: File) => {
  // 验证文件大小
  const isLessThanMaxSize = file.size / 1024 / 1024 < props.maxSize;
  if (!isLessThanMaxSize) {
    ElMessage.error(`文件大小不能超过 ${props.maxSize}MB!`);
    return false;
  }
  
  // 如果是自动上传，则直接上传文件
  if (props.autoUpload) {
    uploadFiles([file]);
  }
  
  return true;
};

// 文件状态改变时的钩子
const handleChange = (file: any, uploadFileList: any[]) => {
  fileList.value = uploadFileList;
  emit('change', file, uploadFileList);
};

// 文件列表移除文件时的钩子
const handleRemove = (file: any, uploadFileList: any[]) => {
  fileList.value = uploadFileList;
  emit('remove', file, uploadFileList);
};

// 手动上传文件
const submitUpload = async () => {
  if (fileList.value.length === 0) {
    ElMessage.warning('请先选择文件');
    return;
  }
  
  const files = fileList.value.map(item => item.raw);
  await uploadFiles(files);
};

// 上传文件
const uploadFiles = async (files: File[]) => {
  loading.value = true;
  
  try {
    const results = await Promise.all(
      files.map(file => {
        if (props.uploadType === 'file') {
          return uploadFile(file, props.fileType);
        } else {
          return uploadImage(file, props.fileType);
        }
      })
    );
    
    ElMessage.success('上传成功');
    emit('success', results);
    
    // 清空文件列表
    fileList.value = [];
  } catch (error: any) {
    ElMessage.error(error.message || '上传失败');
    emit('error', error);
  } finally {
    loading.value = false;
  }
};

// 暴露方法
defineExpose({
  submitUpload,
  fileList
});
</script>

<style scoped>
.file-upload-container {
  margin-bottom: 20px;
}

.upload-actions {
  margin-top: 10px;
  display: flex;
  justify-content: flex-end;
}

:deep(.el-upload-dragger) {
  width: 100%;
  height: 200px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

:deep(.el-icon--upload) {
  font-size: 48px;
  color: #c0c4cc;
  margin-bottom: 10px;
}

:deep(.el-upload__text) {
  color: #606266;
  font-size: 14px;
  text-align: center;
}

:deep(.el-upload__text em) {
  color: #409eff;
  font-style: normal;
}

:deep(.el-upload__tip) {
  font-size: 12px;
  color: #909399;
  margin-top: 10px;
}
</style> 